package com.xltt.watchclient.module.service;

import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanResult;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;

import com.xltt.watchclient.module.bean.ActiveDevice;
import com.xltt.watchclient.module.bean.OptResult;

import java.util.HashMap;
import java.util.Map;

import androidx.annotation.NonNull;

public class BleController implements Handler.Callback {

    // 连接设备
    public static final int START_DEVICE = 0x11;
    // 扫描设备
    public static final int REQUEST_LIST = 0x12;
    // 查看当前连接的设备名称
    public static final int GET_CONNECTED_DEVICES = 0x13;
    // 激活设备
    public static final int ACTIVE_DEVICE = 0x14;
    // 当前连接状态
    public static final int CONNECT_STATE = 0x15;
    // 暂停扫描设备
    public static final int STOP_REQUEST_LIST = 0x16;


    DeviceService mNotificationMonitor;

    public BleController(DeviceService mNotificationMonitor) {
        this.mNotificationMonitor = mNotificationMonitor;
    }

    MyScanCallback mMyScanCallback;
    Messenger lastMessenger;

    public boolean stopScan() {
        if (mMyScanCallback == null || mNotificationMonitor.stopScan(mMyScanCallback)) {
            mMyScanCallback = null;
            return true;
        }
        return false;
    }

    @Override
    public boolean handleMessage(@NonNull Message msg) {
        lastMessenger = msg.replyTo;
        switch (msg.what) {
            case REQUEST_LIST: {
                OptResult mOptResult = new OptResult();
                if (mMyScanCallback == null) {
                    mMyScanCallback = new MyScanCallback();
                }
                mOptResult.type = REQUEST_LIST;
                mOptResult.isSuccess = mNotificationMonitor.startScan(mMyScanCallback);
                reply(mOptResult.toJson(), REQUEST_LIST);
                break;
            }
            case STOP_REQUEST_LIST: {
                OptResult mOptResult = new OptResult();
                mOptResult.type = STOP_REQUEST_LIST;
                mOptResult.isSuccess = stopScan();
                reply(mOptResult.toJson(), REQUEST_LIST);
                break;
            }
            case START_DEVICE: {
                stopScan();
                String addres = msg.getData().getString("result");
                OptResult mOptResult = new OptResult();
                mOptResult.type = START_DEVICE;
                mOptResult.isSuccess = mNotificationMonitor.connectToClient(addres);
                reply(mOptResult.toJson(), START_DEVICE);
                break;
            }
            case GET_CONNECTED_DEVICES: {
                OptResult mOptResult = new OptResult();
                if (mNotificationMonitor.mConnectServer != null) {
                    mOptResult.deviceName = mNotificationMonitor.mConnectServer.getConnectedAddress();
                }
                mOptResult.isSuccess = true;
                mOptResult.type = GET_CONNECTED_DEVICES;
                reply(mOptResult.toJson(), GET_CONNECTED_DEVICES);
                break;
            }
            case ACTIVE_DEVICE: {
                String result = msg.getData().getString("result");
                OptResult mOptResult = new OptResult();
                mOptResult.type = ACTIVE_DEVICE;
                mOptResult.isSuccess = false;
                try {
                    ActiveDevice mActiveDevice = ActiveDevice.fromJson(result);
                    if (mNotificationMonitor.mConnectServer != null) {
                        mOptResult.isSuccess = mNotificationMonitor.mConnectServer.activeDevice(mActiveDevice.name, mActiveDevice.pwd);
                    }
                } catch (Exception ex) {

                }
                reply(mOptResult.toJson(), ACTIVE_DEVICE);
            }
        }

        return false;
    }

    private void reply(String data, int type) {
        if (lastMessenger != null) {
            Message toclient = new Message();
            toclient.what = type;
            Bundle bundle = new Bundle();
            bundle.putString("result", data);
            toclient.setData(bundle);
            try {
                lastMessenger.send(toclient);
            } catch (RemoteException e) {
                lastMessenger = null;
            }
        }
    }

    public void notifyConnectState(int state) {
        OptResult mOptResult = new OptResult();
        mOptResult.isSuccess = true;
        mOptResult.code = state;
        mOptResult.type = CONNECT_STATE;
        reply(mOptResult.toJson(), CONNECT_STATE);
    }


    private class MyScanCallback extends ScanCallback {
        Map<String, BluetoothDevice> _scanResults = new HashMap<>();

        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            HashMap mHashMap = new HashMap<String, String>();
            if (result.getDevice() != null) {
                _scanResults.put(result.getDevice().getAddress(), result.getDevice());
            }

            for (BluetoothDevice device : _scanResults.values()) {
                mHashMap.put(device.getAddress(), device.getName());
            }

            OptResult mOptResult = new OptResult();
            mOptResult.isSuccess = true;
            mOptResult.deviceNames = mHashMap;
            mOptResult.type = REQUEST_LIST;
            reply(mOptResult.toJson(), REQUEST_LIST);
        }

        @Override
        public void onScanFailed(int errorCode) {
            _scanResults.clear();
            OptResult mOptResult = new OptResult();
            mOptResult.isSuccess = false;
            mOptResult.type = REQUEST_LIST;
            reply(mOptResult.toJson(), REQUEST_LIST);
        }
    }
}
